﻿@using zy_simu.Data
@inject SimuCfg emu_cfg
@inject DeviceSnap dev_snap

<style>
    .cell_mark {
    --bs-table-bg: lightyellow;
    }
</style>

<div class="row" style="margin-left: 0px">
    <div class="col-8"> <h5>参数监控</h5> </div>
    <div class="col-4"><Checkbox TValue="bool" @bind-Value="@emu_cfg.params_monitor" ShowAfterLabel="true" DisplayText="使能参数监控" Color="Color.Danger" /></div>
</div>

<div style="font-size: 12px">
    <Table @ref="@PmTable" TItem="CtrlParam" Items="@pm_data.Take(pm_data.Count)" 
    IsStriped="true" IsBordered="true" Height="@_height" AllowResizing="true" IsFixedHeader="true"
    style="--bb-table-td-padding-x: .1rem; --bb-table-td-padding-y: .1rem;"
    ClickToSelect="true" DoubleClickToEdit="true" OnSaveAsync="@OnSaveAsync">
        <TableColumns>
            <TableColumn @bind-Field="@context.name" Text="名称" Width="60" Align="Alignment.Center" Readonly="true" />
            <TableColumn @bind-Field="@context.value" Text="参数值" Width="60" Align="Alignment.Center" OnCellRender="@OnCellRenderHandler" />
            <TableColumn @bind-Field="@context.min" Text="最小值" Width="60" Align="Alignment.Center" Readonly="true" />
            <TableColumn @bind-Field="@context.max" Text="最大值" Width="60" Align="Alignment.Center" Readonly="true" />
            <TableColumn @bind-Field="@context.des" Text="描述" Align="Alignment.Center" Readonly="true" />
        </TableColumns>
    </Table>
</div>


@code {
    public class CtrlParam
    {
        public string name { get; set; } = "";
        public short value { get; set; } = 0;
        public short min { get; set; } = 0;
        public short max { get; set; } = 0;
        public string des { get; set; } = "";

        public int trace { get; set; } = 0;     // 追踪修改的时间, 修改后10s内高亮显示。
        public int pm_tb_idx { get; set; } = 0; // 指示和pm_tb的对应关系
    }

    public Table<CtrlParam>? PmTable { get; set; }
    public List<CtrlParam>? pm_data { get; set; }

    protected override void OnInitialized()
    {
        pm_data = new List<CtrlParam>();
        CtrlParam item = new();
        item.name = "pm name";
        item.value = 0;
        item.min = 0;
        item.max = 0;
        item.des = "pm description";
        item.trace = 1000 * 1000;
        item.pm_tb_idx = 0;
        pm_data.Add(item);
        base.OnInitialized();
    }

    private ZqmParamsTable[] pms_tb = default!;
    public void InitTable(ZqmParamsTable[] dev_pms_tb)
    {
        if (!emu_cfg.params_monitor) return;
        pms_tb = dev_pms_tb;
        pm_data = new List<CtrlParam>();
        for (int i = 0; i < pms_tb.Length; i++)
        {
            CtrlParam item = new();
            item.name = pms_tb[i].name;
            // if (item.name == "NA") continue;
            item.value = 0;
            item.min = pms_tb[i].min;
            item.max = pms_tb[i].max;
            item.des = DevPreDef.pms_des[item.name];
            item.trace = 1000 * 1000;
            item.pm_tb_idx = i;
            pm_data.Add(item);
        }
    }

    // 父组件周期调用，更新数据
    public void UpdateData()
    {
        if (!emu_cfg.params_monitor) return;
        int flag = 0;
        // modified_idx = cnt; // clear modified data index
        for (int i = 0; i < pm_data.Count(); i++)
        {
            if (pm_data[i].value != pms_tb[pm_data[i].pm_tb_idx].val)
            {
                pm_data[i].value = pms_tb[pm_data[i].pm_tb_idx].val;
                pm_data[i].trace = 0;
                flag = 1;
            }
            if (pm_data[i].trace < 10000)
                pm_data[i].trace += 50;
            else if (pm_data[i].trace == 10000)
                flag = 1;                
        }

        if(flag == 1)
            InvokeAsync(StateHasChanged);
    }

    // 数据变化, mark背景黄色10s以作提示
    private static void OnCellRenderHandler(TableCellArgs args)
    {
        if (args.Row is CtrlParam pm && args.ColumnName == "value")
        {
            if(pm.trace < 10000)
            {
                args.Value = $"{pm.value}";
                args.Class = "cell_mark";
            }
        }
    }

    public int modified_idx = -1;
    public short modified_value = 0;
    // 自身改变数据, 记录, TODO 只能记录一组变化
    private Task<bool> OnSaveAsync(CtrlParam item, ItemChangedType changedType)
    {
        if (changedType == ItemChangedType.Update)
        {
            /*
            int cnt = pm_data.Count();
            modified_idx = -1;
            for (int i = 0; i < cnt; i++)
            {
                if (pm_data[i].name == item.name)
                {
                    if (item.value < pm_data[i].min || item.value > pm_data[i].max)
                        continue; // break; 比如冷热柜等有两个TS
                    //pm_data[i].value = item.value; 不主动更新，等待父组件统一更新
                    modified_value = item.value;
                    modified_idx = pm_data[i].pm_tb_idx;
                    break;
                }
            }
            */
            int i = item.pm_tb_idx;
            if (item.value >= pm_data[i].min && item.value <= pm_data[i].max)
            {
                modified_value = item.value;
                modified_idx = i;
            }
        }
        return Task.FromResult(true);
    }

    private int _height = 550;
    public void SetHeight(int height)
    {
        _height = height;
        StateHasChanged();
    }
}
